﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TraderClient.Models
{
    /// <summary>
    /// 表示特定K线序列的类
    /// </summary>
    public class KLineSeries
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="code">代码</param>
        /// <param name="level">K线级别</param>
        /// <param name="unit">K线单位</param>
        /// <param name="size">容量</param>
        public KLineSeries(MarketType market, string code, int level, KLineUnit unit, int size)
        {
            this.Market = market;
            this.Code   = code;
            this.Level  = level;
            this.Unit   = unit;

            this.Series = new List<KLine>(size);
        }

        /// <summary>
        /// 所属交易市场
        /// </summary>
        public MarketType Market { get; set; }

        /// <summary>
        /// 代码（股票代码，期货合约代码等）
        /// </summary>
        public string Code { get; set; }

        /// <summary>
        /// 级别（例如：一分钟或一天）
        /// </summary>
        public int Level { get; set; }

        /// <summary>
        /// K线单位（分钟线，日线等）
        /// </summary>
        public KLineUnit Unit { get; set; }

        /// <summary>
        /// 序列中K线数量
        /// </summary>
        public int Count
        { 
            get { return Series.Count; } 
        }

        /// <summary>
        /// 将一根新K线加入序列
        /// </summary>
        /// <param name="openTime">K线开始时间</param>
        /// <param name="price">开盘价</param>
        public void Add(DateTime openTime, double price)
        {
            KLine k = new KLine(openTime, price);

            this.Add(k);
        }

        /// <summary>
        /// 将一根新K线加入序列
        /// </summary>
        /// <param name="kLine">K线</param>
        public void Add(KLine kLine)
        {
            this.Series.Add(kLine);
        }

        /// <summary>
        /// 获取倒数第二根K线（如果不存在则为空）
        /// </summary>
        public KLine PenultKLine
        {
            get { return Count > 1 ? Series[Count - 2] : null; }
        }

        /// <summary>
        /// 获取最后一根K线（如果不存在则为空）
        /// </summary>
        /// <returns>K线</returns>
        public KLine LastKLine
        {
            get { return Count > 0 ? Series[Count - 1] : null; }
        }

        /// <summary>
        /// K线序列
        /// </summary>
        public List<KLine> Series { get; set; }
    }

    /// <summary>
    /// 表示单根K线数据结构的类
    /// </summary>
    public class KLine
    {
        public KLine(DateTime openTime, double price)
        {
            this.OpenTime = openTime;

            this.Open     = price;
            this.High     = price;
            this.Low      = price;
            this.Close    = price;
        }

        /// <summary>
        /// K线时间
        /// </summary>
        public DateTime OpenTime { get; set; }

        /// <summary>
        /// 最高价
        /// </summary>
        public double High { get; set; }

        /// <summary>
        /// 最低价
        /// </summary>
        public double Low { get; set; }

        /// <summary>
        /// 开盘价
        /// </summary>
        public double Open { get; set; }

        /// <summary>
        /// 收盘价
        /// </summary>
        public double Close { get; set; }

        /// <summary>
        /// 设置K线最新价格并更新最高和最低价格
        /// </summary>
        /// <param name="price">最新价格</param>
        public void SetLastPrice(double price)
        {
            this.Close = price;

            if (this.Close > this.High) this.High = this.Close;
            if (this.Close < this.Low)  this.Low  = this.Close;
        }
    }

    /// <summary>
    /// 表示K线代表的单位（分钟线，日线，周线，月线）
    /// </summary>
    public enum KLineUnit
    {
        /// <summary>
        /// 分钟
        /// </summary>
        Minutes,

        /// <summary>
        /// 日线
        /// </summary>
        Days,

        /// <summary>
        /// 周线
        /// </summary>
        Weeks,

        /// <summary>
        /// 月线
        /// </summary>
        Months
    }

}
